// Created: Dec 13, 2014
//
// Author: wjinwen.1988@gmail.com

#ifndef CHI_NET_CHANNEL_H
#define CHI_NET_CHANNEL_H

#include <algorithm>

#include "chi/net/callbacks.h"

namespace chi {
namespace net {

class EventLoop;

// A selectable I/O channel.
//
// This class doesn't own the file descriptor.
// The file descriptor could be a socket, an eventfd.
class Channel {
 public:
  Channel(EventLoop* loop, const int fd);
  ~Channel();

  void HandleEvent();
  
  void SetReadCallback(EventCallback&& cb) { read_cb_ = std::move(cb); }
  void SetWriteCallback(EventCallback&& cb) { write_cb_ = std::move(cb); }
  void SetCloseCallback(EventCallback&& cb) { close_cb_ = std::move(cb); }
  void SetErrorCallback(EventCallback&& cb) { error_cb_ = std::move(cb); }

  int fd() const { return fd_; }
  
  int events() const { return events_; }
  void set_revents(int revents) { revents_ = revents; }

  void EnableReading();
  void EnableWriting();
  void DisableWriting();
  void DisableAll();
  bool IsWriting() const;
 private:
  void Update();

  static const int kNoneEvent;
  static const int kReadEvent;
  static const int kWriteEvent;

  EventLoop* loop_;
  const int fd_;
  int events_; 
  int revents_;
  EventCallback read_cb_;
  EventCallback write_cb_;
  EventCallback close_cb_;
  EventCallback error_cb_;
};

} 
}

#endif
